/*
File      : Client.java - Communicates with server, has all functions to send info to server in parameter of 
                          method calls on object of server class. This object is obtained using the RMI registry,  
  						  where the object is exposed. An InterfaceObject is created from the reference of RMI registry.
Author    : Kunal Cholera.
Project 4 : Group Chat Application using Java RMI - Remote Method Invocation.
Course    : Distributed Systems.
Institute : University of Southern California - Viterbi School of Engineering.

*/
import java.io.*;
import java.rmi.*;

public class Client{
	
	static String currentUser = null;
	static BufferedReader myInputReader = new BufferedReader( new InputStreamReader ( System.in ));
	static ServerInterface myServerInterfaceObject = null;
	
	static int clientId = 1;
	
	Client(){
		try{
			// Getting an serverobject
			String serverObjectInterfaceUrl = "rmi://localhost:2000/ServerObject";
			myServerInterfaceObject = ( ServerInterface )Naming.lookup( serverObjectInterfaceUrl );
			
			// Registering the client for callback
			//System.out.println("Registering Client.....");
			ClientInterface myClientObject = new ClientImplementation( clientId );
			myServerInterfaceObject.registerForCallback( myClientObject );
			//System.out.println("Setting clientID : " + clientId);
			clientId ++;
			
			//System.out.println("Client registered to the server for callback");
			
		}catch( java.rmi.NotBoundException nbe){ System.out.println( "Kunal : Requested object may not be boud, or server is not running"); System.exit(0);}
		 catch( java.rmi.ConnectException re){ System.out.println("Please start the server first....."); System.exit(0);}
		 catch( Exception e){ System.out.println(e);}
		
	}//end constructor
	
	public int getMenuInput()
	{
		try{
			int menuOption;
			menuOption = Integer.parseInt(myInputReader.readLine());
			return menuOption;
		}catch( java.io.IOException io ){ System.out.println("Error in getUserInput() " + io);}
		
		return 0;// passing the quit argument to quit -. should be handeled in later versions.
		
	}//getMenuInput()
	
	public static String getUserInput()
	{
		try{
			String menuOption = new String(myInputReader.readLine());
			return menuOption;
		}catch( java.io.IOException io ){ System.out.println("Error in getUserInput() " + io);}
		
		return "";// passing the quit argument to quit -. should be handeled in later versions.
	}//getStringInput()
	
	public static Boolean requestService( int menuOption ) throws java.rmi.RemoteException
	{
		switch( menuOption )
		{
		  case 1: // Creating an account
				  System.out.println("Please enter Account Name :");
				  currentUser = Client.getUserInput();
				  myServerInterfaceObject.createAccount( currentUser );
				  System.out.println("\n\nAccount created....");
				  System.out.println("You are now logged in !!\n\n\n");
		 		  break;
		  
		  case 2: // Login checking and requesting
				  System.out.println("Enter Account Name");
				  currentUser = Client.getUserInput();
				  if(! myServerInterfaceObject.checkLoginName( currentUser ))
				  {
					System.out.println("\n\nInvalid Account Name\n\n\n ");
				    return false;
				  }
				  System.out.println("\n\nValid Account Name\n\n\n ");
				  //System.out.println("Valid login name : " + myServerInterfaceObject.checkLoginName( Client.getUserInput ()));
				  break;
		
		  case 3: // showUserStatus() - all valid accounts and all live users.
		          //System.out.println("Active accounts :");
				  System.out.println(myServerInterfaceObject.showUserStatus());
		          break;
		 
		  case 4: // Group chat - with all Live Users..
		          Boolean groupChat = true;
		  		  System.out.println("Group Chat session started....  Enter   quit    ----> to exit");
		 		  String userMessage = new String("");
		          do{ // get the user input and send it to the server function which would call the call back functions....
			          //System.out.println("Inside the do while loop..");
			          userMessage = Client.getUserInput();
					  if( userMessage.equalsIgnoreCase("quit")) 
					  { 
							groupChat = false;
					  }
					  userMessage =  currentUser + " : " + userMessage;
					  myServerInterfaceObject.floodMessage( userMessage );
		
		           //System.out.println("groupChat  : " + groupChat);
	 			  }while( groupChat );
	              System.out.println("\n\n Group Chat ended..."); 
	              break;
	                   		
			
		  default: System.out.println("Please make proper selection"); break;
		}
		
		return true;// TODO think about this one.
		
	}//end requestService()
	
  public static void main( String args[] ){
	Client myClient = new Client();
	int menuOption;
	Boolean validUser = false;
	try{	
		//  Login service.....
		
		do{
			System.out.println(myServerInterfaceObject.displayMenu("loginMenu"));
			try{
			     menuOption = myClient.getMenuInput();
			}catch( java.lang.NumberFormatException nfe )
			 { System.out.println("Please enter only numbers...");
			   menuOption = 99; // to get out of this loop.
             }
			//System.out.println(menuOption);
			
			if( menuOption == 1 || menuOption == 2 || menuOption == 0)
			{
			  validUser = myClient.requestService( menuOption );
			}else { System.out.println("Please enter correct option..");}
	  	  }while(!((menuOption == 1 || menuOption == 2 || menuOption != 0 ) && validUser));

		Boolean serviceRequired = true;
	
	   //  Provide all services....
	    do{
		  System.out.println( myServerInterfaceObject.displayMenu("mainMenu") );
		  try{
      		  menuOption = myClient.getMenuInput();
			}catch( java.lang.NumberFormatException nfe )
			 { 
				System.out.println("Please enter only numbers...");
			    continue;
             }
		  myClient.requestService( menuOption );
		  //menuOption = Integer.parseInt(myInputReader.readLine());
		  //System.out.println("Selection : " + menuOption );
		
		  if( menuOption == 0 ) {serviceRequired = false; }		  
		
	    }while(serviceRequired == true);

	   System.out.println("Logout " + currentUser + " granted : " +myServerInterfaceObject.logout( currentUser ));    
		
	}catch ( Exception e ){ System.out.println("Exception in main try catch block .." + e); }
	
	
  }//end main
}//end class
